#!/usr/bin/env python3
"""
MCP服务启动脚本（Python版本）
启动所有四个MCP服务：Math, Search, TradeTools, LocalPrices
"""

import os
import sys
import time
import signal
import subprocess
from pathlib import Path

class MCPServiceManager:
    def __init__(self):
        self.services = {}
        self.running = True
        
        # Set default ports
        self.ports = {
            'math': int(os.getenv('MATH_HTTP_PORT', '8000')),
            'search': int(os.getenv('SEARCH_HTTP_PORT', '8001')),
            'trade': int(os.getenv('TRADE_HTTP_PORT', '8002')),
            'price': int(os.getenv('GETPRICE_HTTP_PORT', '8003'))
        }
        
        # Service configurations
        self.service_configs = {
            'math': {
                'script': 'tool_math.py',
                'name': 'Math',
                'port': self.ports['math']
            },
            'search': {
                'script': 'tool_search.py',
                'name': 'Search',
                'port': self.ports['search']
            },
            'trade': {
                'script': 'tool_trade.py',
                'name': 'TradeTools',
                'port': self.ports['trade']
            },
            'price': {
                'script': 'tool_get_price_local.py',
                'name': 'LocalPrices',
                'port': self.ports['price']
            }
        }
        
        # Create logs directory
        self.log_dir = Path('../logs')
        self.log_dir.mkdir(exist_ok=True)
        
        # Set signal handlers
        signal.signal(signal.SIGINT, self.signal_handler)
        signal.signal(signal.SIGTERM, self.signal_handler)
    
    def signal_handler(self, signum, frame):
        """处理中断信号"""
        print("\n🛑 收到停止信号，正在关闭所有服务...")
        self.stop_all_services()
        sys.exit(0)
    
    def start_service(self, service_id, config):
        """启动单个服务"""
        script_path = config['script']
        service_name = config['name']
        port = config['port']
        
        if not Path(script_path).exists():
            print(f"❌ Script file not found: {script_path}")
            return False
        
        try:
            # Start service process
            log_file = self.log_dir / f"{service_id}.log"
            # 打开日志文件，用于写入子进程的标准输出和标准错误
            with open(log_file, 'w') as f:
                # 使用 subprocess.Popen 启动子进程
                # sys.executable 确保使用当前 Python 解释器
                # stdout 和 stderr 都重定向到同一个日志文件
                process = subprocess.Popen(
                    [sys.executable, script_path],   # 要执行的命令及参数
                    stdout=f,                        # 标准输出重定向到日志文件
                    stderr=subprocess.STDOUT,         # 标准错误也合并到标准输出（即日志文件）
                    cwd=os.getcwd()                  # 设置子进程工作目录为当前工作目录
                )
            
            self.services[service_id] = {
                'process': process,
                'name': service_name,
                'port': port,
                'log_file': log_file
            }
            
            print(f"✅ {service_name} 服务已启动 (PID: {process.pid}, 端口: {port})")
            return True
            
        except Exception as e:
            print(f"❌ 启动 {service_name} 服务失败: {e}")
            return False
    
    def check_service_health(self, service_id):
        """检查服务健康状态"""
        if service_id not in self.services:
            return False
        
        service = self.services[service_id]
        process = service['process']
        port = service['port']
        
        # 检查进程是否仍在运行
        # 如果子进程已结束，poll() 会返回退出码；仍在运行则返回 None
        if process.poll() is not None:
            return False
        
        # 检查端口是否响应（简单检查）
        try:
            import socket
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            sock.settimeout(1)
            # 尝试连接本地指定端口，connect_ex 返回 0 表示端口已监听（服务正常）
            result = sock.connect_ex(('localhost', port))
            sock.close()
            return result == 0
        except:
            return False
    
    def start_all_services(self):
        """启动所有服务"""
        print("🚀 正在启动MCP服务...")
        print("=" * 50)
        
        print(f"📊 端口配置:")
        for service_id, config in self.service_configs.items():
            print(f"  - {config['name']}: {config['port']}")
        
        print("\n🔄 正在启动服务...")
        
        # Start all services
        for service_id, config in self.service_configs.items():
            self.start_service(service_id, config)
        
        # Wait for services to start
        print("\n⏳ 等待服务启动...")
        time.sleep(3)
        
        # 检查服务状态
        print("\n🔍 检查服务状态...")
        self.check_all_services()
        
        print("\n🎉 所有MCP服务已启动!")
        self.print_service_info()
        
        # Keep running
        self.keep_alive()
    
    def check_all_services(self):
        """检查所有服务状态"""
        for service_id, service in self.services.items():
            if self.check_service_health(service_id):
                print(f"✅ {service['name']} service running normally")
            else:
                print(f"❌ {service['name']} 服务启动失败")
                print(f"   请检查日志文件: {service['log_file']}")
    
    def print_service_info(self):
        """打印服务信息"""
        print("\n📋 服务信息:")
        for service_id, service in self.services.items():
            print(f"  - {service['name']}: http://localhost:{service['port']} (PID: {service['process'].pid})")
        
        print(f"\n📁 日志文件位置: {self.log_dir.absolute()}")
        print("\n🛑 按Ctrl+C停止所有服务")
    
    def keep_alive(self):
        """保持服务运行"""
        try:
            while self.running:
                time.sleep(1)
                
                # 检查服务状态
                for service_id, service in self.services.items():
                    if service['process'].poll() is not None:
                        print(f"\n⚠️  {service['name']} 服务意外停止")
                        self.running = False
                        break
                        
        except KeyboardInterrupt:
            pass
        finally:
            self.stop_all_services()
    
    def stop_all_services(self):
        """停止所有服务"""
        print("\n🛑 正在停止所有服务...")
        
        for service_id, service in self.services.items():
            try:
                service['process'].terminate()
                service['process'].wait(timeout=5)
                print(f"✅ {service['name']} 服务已停止")
            except subprocess.TimeoutExpired:
                service['process'].kill()
                print(f"🔨 {service['name']} 服务已强制停止")
            except Exception as e:
                print(f"❌ 停止 {service['name']} 服务时出错: {e}")
        
        print("✅ 所有服务已停止")
    
    def status(self):
        """显示服务状态"""
        print("📊 MCP服务状态检查")
        print("=" * 30)
        
        for service_id, config in self.service_configs.items():
            if service_id in self.services:
                service = self.services[service_id]
                if self.check_service_health(service_id):
                    print(f"✅ {config['name']} 服务正常运行 (端口: {config['port']})")
                else:
                    print(f"❌ {config['name']} 服务异常 (端口: {config['port']})")
            else:
                print(f"❌ {config['name']} 服务未启动 (端口: {config['port']})")

def main():
    """主函数"""
    if len(sys.argv) > 1 and sys.argv[1] == 'status':
        # 状态检查模式
        manager = MCPServiceManager()
        manager.status()
    else:
        # 启动模式
        manager = MCPServiceManager()
        manager.start_all_services()

if __name__ == "__main__":
    main()
